package com.show.business.device.service.impl;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.show.business.common.TreeSelect;
import com.show.business.device.bean.DeploymentLocation;
import com.show.business.device.mapper.DeploymentLocationMapper;
import com.show.business.device.service.IDeploymentLocationService;
import com.show.business.common.constant.UserConstants;
import com.show.business.common.core.domain.AjaxResult;
import com.show.business.common.utils.StringUtils;
import com.show.business.common.utils.spring.SpringUtils;
import org.springframework.stereotype.Service;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

/**
 * 部署位置管理 服务实现
 *
 * @author ccx
 */
@Service
public class DeploymentLocationServiceImpl extends ServiceImpl<DeploymentLocationMapper, DeploymentLocation> implements IDeploymentLocationService{
    /**
     * 查询部署位置管理数据
     *
     * @param deploymentLocation 部署位置信息
     * @return 部署位置信息集合
     */
    @Override
    public List<DeploymentLocation> getList(DeploymentLocation deploymentLocation)
    {
        return baseMapper.getList(deploymentLocation);
    }

    /**
     * 查询部署位置树结构信息
     *
     * @param deploymentLocation 部署位置信息
     * @return 部署位置树信息集合
     */
    @Override
    public List<TreeSelect> selectDeploymentLocationTreeList(DeploymentLocation deploymentLocation)
    {
        List<DeploymentLocation> deploymentLocations = SpringUtils.getAopProxy(this).getList(deploymentLocation);
        return buildDeploymentLocationTreeSelect(deploymentLocations);
    }

    /**
     * 构建前端所需要树结构
     *
     * @param deploymentLocations 部署位置列表
     * @return 树结构列表
     */
    @Override
    public List<DeploymentLocation> buildDeploymentLocationTree(List<DeploymentLocation> deploymentLocations)
    {
        List<DeploymentLocation> returnList = new ArrayList<DeploymentLocation>();
        List<String> tempList = deploymentLocations.stream().map(DeploymentLocation::getId).collect(Collectors.toList());
        for (DeploymentLocation deploymentLocation : deploymentLocations)
        {
            // 如果是顶级节点, 遍历该父节点的所有子节点
            if (!tempList.contains(deploymentLocation.getParentId()))
            {
                recursionFn(deploymentLocations, deploymentLocation);
                returnList.add(deploymentLocation);
            }
        }
        if (returnList.isEmpty())
        {
            returnList = deploymentLocations;
        }
        return returnList;
    }

    /**
     * 构建前端所需要下拉树结构
     *
     * @param deploymentLocations 部署位置列表
     * @return 下拉树结构列表
     */
    @Override
    public List<TreeSelect> buildDeploymentLocationTreeSelect(List<DeploymentLocation> deploymentLocations)
    {
        List<DeploymentLocation> deploymentLocationTrees = buildDeploymentLocationTree(deploymentLocations);
        return deploymentLocationTrees.stream().map(TreeSelect::new).collect(Collectors.toList());
    }

    /**
     * 根据部署位置ID查询信息
     *
     * @param id 部署位置ID
     * @return 部署位置信息
     */
    @Override
    public DeploymentLocation selectDeploymentLocationById(String id)
    {
        return baseMapper.selectDeploymentLocationById(id);
    }

    /**
     * 根据ID查询所有子部署位置（正常状态）
     *
     * @param id 部署位置ID
     * @return 子部署位置数
     */
    @Override
    public int selectNormalChildrenDeploymentLocationById(String id)
    {
        return baseMapper.selectNormalChildrenDeploymentLocationById(id);
    }

    /**
     * 是否存在子节点
     *
     * @param id 部署位置ID
     * @return 结果
     */
    @Override
    public boolean hasChildByDeploymentLocationId(String id)
    {
        int result = baseMapper.hasChildByDeploymentLocationId(id);
        return result > 0;
    }

    /**
     * 校验部署位置名称是否唯一
     *
     * @param deploymentLocation 部署位置信息
     * @return 结果
     */
    @Override
    public boolean checkDeploymentLocationNameUnique(DeploymentLocation deploymentLocation)
    {
        String classId = StringUtils.isNull(deploymentLocation.getId()) ? "" : deploymentLocation.getId();
        DeploymentLocation info = baseMapper.checkDeploymentLocationNameUnique(deploymentLocation.getName(), deploymentLocation.getParentId());
        if (StringUtils.isNotNull(info) && !info.getId().equals(classId))
        {
            return UserConstants.NOT_UNIQUE;
        }
        return UserConstants.UNIQUE;
    }

    /**
     * 新增保存部署位置信息
     *
     * @param deploymentLocation 部署位置信息
     * @return 结果
     */
    @Override
    public AjaxResult insertDeploymentLocation(DeploymentLocation deploymentLocation){
        if(StrUtil.hasBlank(deploymentLocation.getName())){
            return AjaxResult.error("名称不能为空");
        }
        if(baseMapper.repeatNameNum(deploymentLocation) > 0){
            return AjaxResult.error("名称不能重复");
        }
        /**类型（0：路段；1：场地 ；2：位置）*/
        if(!deploymentLocation.getLocationType().equals("0")) {
            DeploymentLocation info = baseMapper.selectDeploymentLocationById(deploymentLocation.getParentId());
            deploymentLocation.setAncestors(info.getAncestors() + "," + deploymentLocation.getParentId());
        }
        baseMapper.insert(deploymentLocation);
        return AjaxResult.success();
    }

    /**
     * 修改保存部署位置信息
     *
     * @param deploymentLocation 部署位置信息
     * @return 结果
     */
    @Override
    public AjaxResult updateDeploymentLocation(DeploymentLocation deploymentLocation){
        if(StrUtil.hasBlank(deploymentLocation.getName())){
            return AjaxResult.error("类目名称不能为空");
        }
        if(baseMapper.repeatNameNum(deploymentLocation) > 0){
            return AjaxResult.error("类目名称不能重复");
        }
        DeploymentLocation newParentDeploymentLocation = baseMapper.selectDeploymentLocationById(deploymentLocation.getParentId());
        DeploymentLocation oldDeploymentLocation = baseMapper.selectDeploymentLocationById(deploymentLocation.getId());
        if (StringUtils.isNotNull(newParentDeploymentLocation) && StringUtils.isNotNull(oldDeploymentLocation))
        {
            String newAncestors = newParentDeploymentLocation.getAncestors() + "," + newParentDeploymentLocation.getId();
            String oldAncestors = oldDeploymentLocation.getAncestors();
            deploymentLocation.setAncestors(newAncestors);
            updateDeploymentLocationChildren(deploymentLocation.getId(), newAncestors, oldAncestors);
        }
        baseMapper.updateById(deploymentLocation);
        return AjaxResult.success();
    }

    /**
     * 修改子元素关系
     *
     * @param id 被修改的部署位置ID
     * @param newAncestors 新的父ID集合
     * @param oldAncestors 旧的父ID集合
     */
    public void updateDeploymentLocationChildren(String id, String newAncestors, String oldAncestors)
    {
        List<DeploymentLocation> children = baseMapper.selectChildrenDeploymentLocationById(id);
        for (DeploymentLocation child : children)
        {
            child.setAncestors(child.getAncestors().replaceFirst(oldAncestors, newAncestors));
        }
        if (children.size() > 0)
        {
            baseMapper.updateDeploymentLocationChildren(children);
        }
    }

    /**
     * 删除部署位置管理信息
     *
     * @param classId 部署位置ID
     * @return 结果
     */
    @Override
    public AjaxResult delInfo(String classId)
    {
        baseMapper.updateDel(classId);
        return AjaxResult.success();
    }
    /**
     * 查询部署位置管理数据
     *
     * @param deploymentLocation 部署位置信息
     * @return 部署位置信息集合
     */
    @Override
    public List<DeploymentLocation> getAppList(DeploymentLocation deploymentLocation) {
        if(StrUtil.isBlank(deploymentLocation.getParentId())){
            deploymentLocation.setParentId("0");
        }
        return baseMapper.getList(deploymentLocation);
    }

    /**
     * 递归列表
     */
    private void recursionFn(List<DeploymentLocation> list, DeploymentLocation t)
    {
        // 得到子节点列表
        List<DeploymentLocation> childList = getChildList(list, t);
        t.setChildren(childList);
        for (DeploymentLocation tChild : childList)
        {
            if (hasChild(list, tChild))
            {
                recursionFn(list, tChild);
            }
        }
    }

    /**
     * 得到子节点列表
     */
    private List<DeploymentLocation> getChildList(List<DeploymentLocation> list, DeploymentLocation t)
    {
        List<DeploymentLocation> tlist = new ArrayList<DeploymentLocation>();
        Iterator<DeploymentLocation> it = list.iterator();
        while (it.hasNext())
        {
            DeploymentLocation n = (DeploymentLocation) it.next();
            if (StringUtils.isNotNull(n.getParentId()) && n.getParentId() .equals(t.getId()))
            {
                tlist.add(n);
            }
        }
        return tlist;
    }

    /**
     * 判断是否有子节点
     */
    private boolean hasChild(List<DeploymentLocation> list, DeploymentLocation t)
    {
        return getChildList(list, t).size() > 0;
    }

    /**
     * 查询部署位置
     * @return
     */
    @Override
    public List<DeploymentLocation> getDeploymentLocationList() {
        List<DeploymentLocation> deploymentLocation1 = baseMapper.checkDeploymentLocationByLocationType("0");
        List<DeploymentLocation> deploymentLocation2 = baseMapper.checkDeploymentLocationByLocationType("1");
        List<DeploymentLocation> deploymentLocation3 = baseMapper.checkDeploymentLocationByLocationType("2");
        // 先组装二级类目和三级类目
        Map<String,List<DeploymentLocation>> threeMap = deploymentLocation3.stream().collect(Collectors.groupingBy(DeploymentLocation::getParentId));
        deploymentLocation2.stream().forEach(k->{
            if(threeMap.get(k.getId()) != null && threeMap.get(k.getId()).size() > 0){
                k.setChildren(threeMap.get(k.getId()));
            }
        });
        Map<String,List<DeploymentLocation>> twoMap = deploymentLocation2.stream().collect(Collectors.groupingBy(DeploymentLocation::getParentId));
        deploymentLocation1.stream().forEach(k->{
            if(twoMap.get(k.getId()) != null && twoMap.get(k.getId()).size() > 0){
                k.setChildren(twoMap.get(k.getId()));
            }
        });
        return deploymentLocation1;
    }
    /**
     * 查询部署位置数据
     * @param  locationType 类型（0：路段；1：场地 ；2：位置）
     * @return 部署位置信息集合
     */
    @Override
    public List<DeploymentLocation> checkDeploymentLocationByLocationType(String locationType){
        return baseMapper.checkDeploymentLocationByLocationType(locationType);
    }
    /**
     * 根据父类ID获取子集列表
     * @param  parentId 父级id
     * @return 部署位置信息集合
     */
    @Override
    public List<DeploymentLocation> getChildrenListByParentId(String parentId) {
        return baseMapper.getChildrenListByParentId(parentId);
    }
}
